﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace OK.SCOM.Authoring.Tools.MPElementsExtract
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				if (args.Length != 2 && args.Length != 3)
				{
					throw new Exception("Invalid parameters. Please see usage for details.");
				}

				string sMpFile = args[0];

				if (!File.Exists(sMpFile))
				{
					throw new FileNotFoundException("MP file not found", sMpFile);
				}

				XmlDocument xmlMp = new XmlDocument();
				xmlMp.Load(sMpFile);

				FileInfo fi = new FileInfo(sMpFile);

				// default destination subfolder - MP name
				string destSubDir = fi.Name.Remove(fi.Name.Length - fi.Extension.Length);
				string destSubDirForScripts = "Scripts";
				string destSubDirForSubScripts = "SubScripts";
				string destSubDirForReports = "Reports";
				string destSubDirForLinkedReports = "LinkedReports";
				string destSubDirForDWScripts = "DWScripts";
				string destSubDirForDWSubScripts = "DWSubScripts";
				string destSubDirForReportResources = "ReportResources";

				// default destination folder - same as MP's folder
				string destDir = fi.Directory.FullName;
				string sourceDir = fi.Directory.FullName;

				// try to get destination folder from arguments
				if(args.Length==3 && args[2].StartsWith("/destination:"))
				{
					string customDir = args[2].ToLower().Replace("/destination:", "");
					if (Directory.Exists(customDir))
					{
						destDir = customDir;
					}
					else throw new Exception(String.Format("Destination directory '{0}' not found", customDir));
				}
				else if (args.Length == 3) throw new Exception(String.Format("Unknown parameter {0}", args[2]));

				DirectoryInfo diDestDir = new DirectoryInfo(destDir);
				// creating destination subfolder
				if (!Directory.Exists(Path.Combine(destDir,destSubDir))) diDestDir.CreateSubdirectory(destSubDir);

				string baseDir = (args[1].ToLower().StartsWith("/em")) ? sourceDir : Path.Combine(destDir, destSubDir);

				DirectoryInfo diDestSubDir = new DirectoryInfo(Path.Combine(destDir, destSubDir));

				MPProcessor processor = new MPProcessor();
				MPElementTypeScript etScript = new MPElementTypeScript(baseDir, destSubDirForScripts);
				processor.AddElementType(etScript);

				MPElementTypeScript etSubScript = new MPElementTypeScript(baseDir, destSubDirForSubScripts);
				etSubScript.Mode = MPElementTypeScript.ExtractionMode.SubScriptsExtract;
				processor.AddElementType(etSubScript);

				MPElementTypeReport etReport = new MPElementTypeReport(baseDir, destSubDirForReports);
				etReport.Mode = MPElementTypeReport.ExtractionMode.Reports;
				processor.AddElementType(etReport);

				MPElementTypeReport etLinkedReport = new MPElementTypeReport(baseDir, destSubDirForLinkedReports);
				etLinkedReport.Mode = MPElementTypeReport.ExtractionMode.LinkedReports;
				processor.AddElementType(etLinkedReport);

				MPElementTypeDWScript etDWScripts = new MPElementTypeDWScript(baseDir, destSubDirForDWScripts);
				etDWScripts.Mode = MPElementTypeDWScript.ExtractionMode.ScriptsExtract;
				processor.AddElementType(etDWScripts);

				MPElementTypeDWScript etDWSubScripts = new MPElementTypeDWScript(baseDir, destSubDirForDWSubScripts);
				etDWSubScripts.Mode = MPElementTypeDWScript.ExtractionMode.SubScriptsExtract;
				processor.AddElementType(etDWSubScripts);

				MPElementTypeReportResource etReportResources = new MPElementTypeReportResource(baseDir, destSubDirForReportResources);
				processor.AddElementType(etReportResources);

				if (args[1].ToLower().StartsWith("/ex"))
				{
					processor.Parse(xmlMp, ParseAction.ExtractNoPlaceMarks);
				}
				else if (args[1].ToLower().StartsWith("/p"))
				{
					processor.Parse(xmlMp, ParseAction.ExtractReplaceWithPlaceMarks);
					SaveMP(xmlMp,diDestSubDir.FullName + "\\" + fi.Name);
				}
				else if (args[1].ToLower().StartsWith("/em"))
				{
					processor.Parse(xmlMp, ParseAction.Embed);
					SaveMP(xmlMp, diDestSubDir.FullName + "\\" + fi.Name);
				}
				else throw new Exception(String.Format("Unknown parameter {0}",args[1]));

			}
			catch (Exception ex)
			{
				PrintError(ex.Message);
				PrintUsage();
			}
		}

		static void SaveMP(XmlDocument mp, string path)
		{
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.Indent = true;
			settings.OmitXmlDeclaration = true;
			settings.Encoding = Encoding.Unicode;

			XmlWriter xmlwriter = XmlWriter.Create(path, settings);
			mp.Save(xmlwriter);
			//xmlwriter.Flush();
			xmlwriter.Close();

		}

		static void PrintUsage()
		{
			Console.WriteLine("USAGE:");
			Console.WriteLine("MPElementsExtract.exe <MP.xml> </em[bed]|/ex[tract]|/p[utplacemarks]> [/destination:<directory>]");
		}

		static void PrintError(string message)
		{
			Console.WriteLine("ERROR: {0}", message);
		}
	}
}
